#pragma once
#include <vector>
#include <math.h>
#include <time.h>
using namespace std;
#include <boost/lexical_cast.hpp>
#include <typeinfo.h>
#include <iostream>

#define RAD2DEG (180./3.1415926535897932)
#define DEG2RAD (3.1415926535897932/180.)
// safe sum
float SafeSum		(const vector<float>& vcVec_ );
float ExtraSafeSum	(const vector<float>& vcVec_);

// easy vector assignment
void AssignVec3		(vector<float>* vector, const float& val0, const float& val1, const float& val2);
void AssignVec4		(vector<float>* vector, const float& val0, const float& val1, const float& val2, const float& val3);

// randomized random
void InitRand();
// generate a rand double value from 0 to 1. included
double Randrand();
// generate a rand double value from dLower to dUpper
double RandLim(double dLower_, double dUpper_);
// generate a rand integer from 0 to nTotal_-1 included
int RandIdx(int nTotal_);
// generate a random inter from nLower_ to nUpper_-1;
int RandLim(int nLower_, int nUpper_);

// string manipulator
template <class T>
inline void StringPlusInt(string& sOut_, const string& sMsg_, const T& tVal_)
{
    // insert number into string using sprintf syntax (example call: StringPlusInt(&sSomeString, &string("Run #%d"), _nNum);)
    char cTemp[256];
    sprintf_s(cTemp,256,sMsg_.c_str(),tVal_);
    sOut_.assign(cTemp);
}


namespace helpers {
    template<class T, class charT>
    void validate(T& v,const std::basic_string<charT>& s)
    {
        try
        {
            v = boost::lexical_cast<T>(s);
        }

        catch(const boost::bad_lexical_cast&)
        {
            std::string sErr("fatal error: string \"");
            sErr += (s + "\" not convertible to " + typeid(T).name());
            throw exception(sErr.c_str());
        }
    }

    template<class T, class charT>
    T validate(const std::basic_string<charT>& s)
    {
        T v;
        validate(v,s);
        return v;
    }
}
